﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Extensions.DependencyInjection;
using PowerTestController.Communication;
using PowerTestController.Models;
using System.Windows;

namespace PowerTestController.ViewModes
{
    public class MessageInfo
    {
        public bool message;
    }

    public partial class MainViewModel : ObservableRecipient, IRecipient<MessageInfo>
    {
        private SerialPortCommunication communication;
        private bool selectPortName;

        public MainViewModel()
        {
            //激活OnActivated
            IsActive = true;
            communication = App.Current.Services.GetRequiredService<SerialPortCommunication>();
            SourceM1 = new SourceModel() { IpAddress = "192.168.0.179", PortNum = 5000 };
            SourceM2 = new SourceModel() { IpAddress = "192.168.0.180", PortNum = 5000 };
            mainParamModel = new MainModel();
            RefreshPortList();
            MainParamModel.SelectPortName = MainParamModel.PortNameItems[0];
        }

        #region 消息注册与接收
        public void Receive(MessageInfo message)
        {
            selectPortName = message.message;
        }

        protected override void OnActivated()
        {
            Messenger.RegisterAll(this, "Main");
        }

        #endregion

        #region 属性

        /// <summary>
        /// 设备参数
        /// </summary>
        [ObservableProperty]
        private MainModel mainParamModel;

        /// <summary>
        /// ITECH 电源1数据
        /// </summary>
        [ObservableProperty]
        private SourceModel _sourceM1;

        /// <summary>
        /// ITECH 电源2数据
        /// </summary>
        [ObservableProperty]
        private SourceModel _sourceM2;

        /// <summary>
        /// 是否开始连接设备
        /// </summary>
        [ObservableProperty]
        private bool isConnectDevice = false;
        #endregion
        public void RefreshPortList()
        {
            if (OperatingSystem.IsWindows())
            {
                // 获取所有可用串口的名称数组
                string[] portNames = System.IO.Ports.SerialPort.GetPortNames();
                if (portNames.Length > 0 && portNames.Length != MainParamModel.PortNameItems.Count)
                {
                    MainParamModel.PortNameItems.Clear();
                    foreach (string portName in portNames)
                    {
                        MainParamModel.PortNameItems.Add(portName);
                    }
                }
                else
                {
                    Console.WriteLine("未找到可用串口。");
                }
            }
        }

        #region 命令

        #region 连接命令
        [RelayCommand(CanExecute = nameof(CanConnectExecute))]
        private void ConnectDevice()
        {
            bool flag = false;
            try
            {
                Task.Run(
                    () =>
                    {
                        if (IsConnectDevice)
                        {
                            if (SourceM1.IpAddress == null || SourceM2.IpAddress == null)
                            {
                                MessageBox.Show("IP地址不能为null");
                                IsConnectDevice = false;
                                return;
                            }
                            if (!InitSourceDevice(SourceM1, "一级电源"))
                            {
                                IsConnectDevice = false;
                                return;
                            }
                            if (!InitSourceDevice(SourceM2, "二级电源"))
                            {
                                IsConnectDevice = false;
                                return;
                            }

                            flag = communication.ConnectDevice(MainParamModel.SelectPortName);
                            if (!flag)
                            {
                                _ = MessageBox.Show("功率计连接失败，请检查！");
                                IsConnectDevice = false;
                                return;
                            }

                            CircleReadPowerAndCurrent();
                        }
                        else
                        {
                            SourceM1.SCPI_Communication?.Close();
                            SourceM2.SCPI_Communication?.Close();
                            communication?.DisposeSerialPort();
                        }
                    }
                );
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
            finally
            {
                SetParamCommand.NotifyCanExecuteChanged();
                MonitoringDevicePowerCommand.NotifyCanExecuteChanged();
            }
        }

        private bool InitSourceDevice(SourceModel sourceModel, string deviceName)
        {
            sourceModel.SCPI_Communication = new ITECH_SCPI_Communication();
            string? mes = sourceModel.SCPI_Communication.Open(sourceModel.IpAddress, sourceModel.PortNum);
            if (mes != null)
            {
                _ = MessageBox.Show($"{deviceName} {mes}请检查！", "错误");
                return false;
            }
            //连接电源后设置为程控模式以及恒流模式
            if (!sourceModel.SCPI_Communication.SetControlMode())
            {
                _ = MessageBox.Show($"{deviceName}设置程控模式失败，请检查！");
                return false;
            }
            if (!sourceModel.SCPI_Communication.SetCCMode())
            {
                _ = MessageBox.Show($"{deviceName}设置恒流模式失败，请检查！");
                return false;
            }
            return true;
        }

        private void CircleReadPowerAndCurrent()
        {
            Task.Run(
                () =>
                {
                    while (IsConnectDevice)
                    {
                        SourceM1.CurrentGet = SourceM1!.SCPI_Communication!.GeTRealCurrent();
                        Thread.Sleep(100);
                    }
                }
            );
            Task.Run(
                () =>
                {
                    while (IsConnectDevice)
                    {
                        SourceM2.CurrentGet = SourceM2!.SCPI_Communication!.GeTRealCurrent();
                        Thread.Sleep(100);
                    }
                }
            );
            Task.Run(
                () =>
                {
                    while (IsConnectDevice)
                    {
                        MainParamModel.PowerCurrentGet = communication.ReadPower() ?? 0.0;
                        Thread.Sleep(100);
                    }
                }
            );
        }

        private bool CanConnectExecute()
        {
            return !MainParamModel.IsStartMonitoring;
        }
        #endregion

        #region 设置命令
        [RelayCommand(CanExecute = nameof(CanSetParamExecute))]
        private async Task SetParam()
        {
            try
            {
                await Task.Run(
                    () =>
                    {
                        //先设置  再读取 确保正确
                        bool? flag = SourceM1.SCPI_Communication?.SetCurrent(SourceM1.CurrentSet);
                        if (flag != true)
                        {
                            MessageBox.Show("设置一级电流失败！");
                            return;
                        }
                        flag = SourceM2.SCPI_Communication?.SetCurrent(SourceM2.CurrentSet);
                        if (flag != true)
                        {
                            MessageBox.Show("设置二级电流失败！");
                            return;
                        }
                    }
                );
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        private bool CanSetParamExecute()
        {
            return IsConnectDevice;
        }
        #endregion

        #region 监测命令
        [RelayCommand(CanExecute = nameof(CanMonitoringDevicePowerExecute))]
        private async Task MonitoringDevicePower()
        {
            try
            {
                await Task.Run(
                    async () =>
                    {
                        while (MainParamModel.IsStartMonitoring)
                        {
                            if (MainParamModel.JudgePowerIsAlarm())
                            {
                                CloseSource(SourceM2);

                                await Task.Delay(SourceM2.StartDelay * 1000);

                                CloseSource(SourceM1);

                                MessageBox.Show("功率异常超出功率设定范围，已关闭电源，请检查设备");
                                return;
                            }
                        }
                    }
                );
            }
            catch (Exception ex)
            {
                throw;
            }
            finally
            {
                MainParamModel.IsStartMonitoring = false;
                ConnectDeviceCommand.NotifyCanExecuteChanged();
            }
        }

        private bool CloseSource(SourceModel sourceModel)
        {
            //先断电，按顺序；先断二级，延时同二级开启延时时长一致，再断一级
            if (!sourceModel.SCPI_Communication!.SetOutput(false))
            {
                //失败再次尝试
                if (!sourceModel.SCPI_Communication!.SetOutput(false))
                {
                    MessageBox.Show("关闭二级电源失败，请检查！");
                    return false;
                }
            }
            return true;
        }

        private bool CanMonitoringDevicePowerExecute()
        {
            return IsConnectDevice;
        }
        #endregion

        #endregion

    }
}
